﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BattleFury.Lib.Controls
{
	public class UserInterface
	{
		public string Name { get; set; }
		public Skin Skin { get; set; }
		public SpriteFont Font { get; set; }
		public List<IControl> Controls { get; set; }

		public SpriteBatch SpriteBatch { get { return RenderEngine.Get().SpriteBatch; } }

		public UserInterface()
		{
			Controls = new List<IControl>();
		}

		public void Deserialize(object callingObject, string path)
		{
			var filename = Path.GetFullPath(path);
			if (!File.Exists(filename))
				throw new FileNotFoundException(filename, filename);

			var doc = XDocument.Load(filename);

			var root = (from e in doc.Elements() where e.Name == "UserInterface" select e).SingleOrDefault();

			Name = root.Attribute("Name").Value;
			var skinName = root.Attribute("Skin").Value;
			var fontName = root.Attribute("Font").Value;

			if (!string.IsNullOrEmpty(skinName))
			{
				Skin = RenderEngine.Get().Content.Load<Skin>(skinName);
				Skin.CachePartNames();
				Skin.LoadTexture();
			}
			if (!string.IsNullOrEmpty(fontName)) Font = RenderEngine.Get().Content.Load<SpriteFont>(fontName);

			if (root != null)
			{
				var children = (from c in root.Elements() select c);
				foreach (var child in children)
				{
					var name = child.Name.LocalName;
					var type = Type.GetType("BattleFury.Lib.Controls." + name);
					if (type == null) continue;
					var ctrl = (Control)Activator.CreateInstance(type);
					if (ctrl == null) continue;
					ctrl.Deserialize(child, callingObject);
					ctrl.Skin = Skin;
					ctrl.Font = Font;
					Controls.Add(ctrl);
				}
			}

			Controls.OrderBy(x => x.GetType() == typeof(Console));
			Controls.Reverse();

		}

		public void Serialize()
		{

		}

		public void Update(GameTime gameTime)
		{
			foreach (var control in Controls)
			{
				if (control.IsEnabled) control.Update(gameTime);
			}
		}

		public void Draw(GameTime gameTime)
		{
			SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);
			foreach (var control in Controls)
			{
				if (control.IsVisible) control.Draw(gameTime);
			}
			SpriteBatch.End();
		}

		public IControl GetControl(string name)
		{
			foreach (var control in Controls.Where(control => control.Name == name))
			{
				return control;
			}
			return null;
		}
	}
}